home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
prev
/
prev.lha
/
cone.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-10
|
4KB
|
220 lines
#include <math.h>
#include <stdio.h>
#include <vogle.h>
#include "art.h"
#include "macro.h"
#include "gram.h"
extern int lookatdone;
extern int longlines;
extern mats *mstackp;
extern hlist *fhlist;
extern float tolerance;
/*
* coneinit
*
* initialise the function pointers and fields for a cone object,
* returning its pointer.
*/
void
coneinit(o, d)
object *o;
details *d;
{
int first, faces;
vector base, tip, basescale, tipscale, tmp;
details *ld;
float grad;
float apex_x, apex_y, apex_z, apex_r;
float base_x, base_y, base_z, base_r;
float len0, len1, len_x, len_y, len_z;
float cosine, sine, dx1, dy1, dx2, dy2, delta;
float cx1, cy1, cx2, cy2;
int i;
Matrix m;
if (!lookatdone)
deflookat();
faces = 0;
first = 1;
base.x = base.y = base.z = 0.0;
tip.x = tip.y = tip.z = 1.0;
basescale.x = basescale.y = 1.0;
tipscale.x = tipscale.y = 0.0;
while (d != (details *)NULL) {
switch (d->type) {
case VERTEX:
tip = d->u.v;
break;
case CENTER:
if (faces == 0)
base = d->u.v;
else
tip = d->u.v;
faces++;
break;
case RADIUS:
if (first) {
basescale.x = basescale.y = d->u.f;
first = 0;
} else
tipscale.x = tipscale.y = d->u.f;
break;
case RADII:
if (first) {
tipscale.x = d->u.v.x;
tipscale.y = d->u.v.y;
first = 0;
} else {
basescale.x = d->u.v.x;
basescale.y = d->u.v.y;
}
break;
default:
warning("art: illegal field in cone ignored.\n");
}
ld = d;
d = d->nxt;
free(ld);
}
/* this axis is done in obj_transform */
basescale.z = tipscale.z = 1.0;
if (faces == 2) {
if (tipscale.x > basescale.x) {
tmp = tip;
tip = base;
base = tmp;
tmp = tipscale;
tipscale = basescale;
basescale = tmp;
}
o->obj.cne_tipval = tipscale.x / basescale.x;
grad = (tip.x - base.x) / (basescale.x - tipscale.x);
tip.x += grad * tipscale.x;
grad = (tip.y - base.y) / (basescale.x - tipscale.x);
tip.y += grad * tipscale.x;
grad = (tip.z - base.z) / (basescale.x - tipscale.x);
tip.z += grad * tipscale.x;
} else
o->obj.cne_tipval = 0.0;
tmp.x = (tip.x + base.x) / 2.0;
tmp.y = (tip.y + base.y) / 2.0;
tmp.z = (tip.z + base.z) / 2.0;
len_x = tip.x - base.x;
len_y = tip.y - base.y;
len_z = tip.z - base.z;
len0 = sqrt(len_x * len_x + len_y * len_y + len_z * len_z);
len1 = sqrt(len_x * len_x + len_z * len_z);
/*
* Draw the axis center line in YELLOW
*/
color(YELLOW);
move(tip.x, tip.y, tip.z);
draw(base.x, base.y, base.z);
/*
* And the rest in GREEN...
*/
color(GREEN);
pushmatrix();
calctransforms(mstackp);
multmatrix(mstackp->obj2ray);
translate(base.x, base.y, base.z);
identmatrix(m);
if (len1 == 0.0) {
cosine = 0.0;
sine = 1.0;
} else {
cosine = len_z / len1;
sine = len_x / len1;
}
/* rotate about y */
m[0][0] = cosine;
m[0][2] = -sine;
m[2][0] = sine;
m[2][2] = cosine;
multmatrix(m);
identmatrix(m);
if (len0 == 0.0) {
cosine = 0.0;
sine = 1.0;
} else {
cosine = len1 / len0;
sine = -len_y / len0;
}
/* rotate about x */
m[1][1] = cosine;
m[1][2] = sine;
m[2][1] = -sine;
m[2][2] = cosine;
multmatrix(m);
/*
* Draw the end circles...
*/
pushmatrix();
scale(basescale.x, basescale.y, 1.0);
circle (0.0, 0.0, 1.0);
pushmatrix();
scale(tipscale.x, tipscale.y, 1.0);
translate(0.0, 0.0, len0);
circle (0.0, 0.0, 1.0);
popmatrix();
popmatrix();
/*
* Draw the logitudinal lines...
*/
delta = 2 * PI / longlines;
cosine = cos(delta);
sine = sin(delta);
cx1 = basescale.x;
cy1 = 0.0;
cx2 = tipscale.x;
cy2 = 0.0;
move(cx1, cy1, 0.0);
draw(cx2, cy2, len0);
for (i = 0; i < longlines; i++) {
dx1 = cx1;
dy1 = cy1;
cx1 = dx1 * cosine - dy1 * sine;
cy1 = dx1 * sine + dy1 * cosine;
dx2 = cx2;
dy2 = cy2;
cx2 = dx2 * cosine - dy2 * sine;
cy2 = dx2 * sine + dy2 * cosine;
move(cx1, cy1, 0.0);
draw(cx2, cy2, len0);
}
popmatrix();
}